package com.weifly.weistock.record.data.impl;

import com.weifly.weistock.record.data.DataStoreService;
import com.weifly.weistock.record.data.domain.StockDataDto;
import com.weifly.weistock.record.data.domain.StockDayDto;
import org.apache.commons.io.IOUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentFactory;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * 数据存储服务实现
 *
 * @author weifly
 * @since 2019/9/29
 */
public class DataStoreServiceImpl implements DataStoreService {

    private Logger log = LoggerFactory.getLogger(DataStoreServiceImpl.class);

    private static final String ELE_ROOT = "root";
    private static final String ELE_RECORD = "record";
    private static final String ATTR_STOCK = "stock";
    private static final String ATTR_DAY = "day";
    private static final String ATTR_OPEN = "open";
    private static final String ATTR_HIGH = "high";
    private static final String ATTR_LOW = "low";
    private static final String ATTR_CLOSE = "close";

    private String configPath; // 配置文件路径

    public void setConfigPath(String configPath) {
        this.configPath = configPath;
    }

    @Override
    public List<StockDataDto> loadStockDataList() {
        List<StockDataDto> stockList = new ArrayList<>();

        File configFolder = new File(this.configPath);
        if(!configFolder.exists()){
            log.info("股票数据目录不存在：" + configFolder.getAbsolutePath());
            return stockList;
        }

        for(File xmlFile : configFolder.listFiles()){
            if(xmlFile.getName().endsWith(".xml")){
                log.info("加载股票数据：" + xmlFile.getAbsolutePath());
                StockDataDto stockDto = this.loadDataXml(xmlFile);
                stockList.add(stockDto);
            }
        }
        return stockList;
    }

    private StockDataDto loadDataXml(File xmlFile){
        StockDataDto stockDto = new StockDataDto();
        try{
            SAXReader reader = new SAXReader();
            Document document = reader.read(xmlFile);
            Element rootEle = document.getRootElement();

            String stockCode = rootEle.attributeValue(ATTR_STOCK);
            stockDto.setCode(stockCode);

            List<Element> recordEleList = rootEle.elements(ELE_RECORD);
            if(recordEleList!=null){
                for(Element recordEle : recordEleList){
                    StockDayDto dayDto = new StockDayDto();
                    String day = recordEle.attributeValue(ATTR_DAY);
                    dayDto.setDay(day);

                    String openStr = recordEle.attributeValue(ATTR_OPEN);
                    double open = Double.parseDouble(openStr);
                    dayDto.setOpen(open);

                    String highStr = recordEle.attributeValue(ATTR_HIGH);
                    double high = Double.parseDouble(highStr);
                    dayDto.setHigh(high);

                    String lowStr = recordEle.attributeValue(ATTR_LOW);
                    double low = Double.parseDouble(lowStr);
                    dayDto.setLow(low);

                    String closeStr = recordEle.attributeValue(ATTR_CLOSE);
                    double close = Double.parseDouble(closeStr);
                    dayDto.setClose(close);

                    stockDto.getDayList().add(dayDto);
                }
            }
            return stockDto;
        }catch(DocumentException e){
            log.error("", e);
            throw new RuntimeException(e);
        }
    }

    @Override
    public void saveStockData(StockDataDto stockDto) {
        File configFolder = new File(this.configPath);
        if(!configFolder.exists()){
            configFolder.mkdirs();
        }

        DocumentFactory factory = DocumentFactory.getInstance();

        Document document = factory.createDocument();
        document.setXMLEncoding("UTF8");

        Element rootEle = factory.createElement(ELE_ROOT);
        rootEle.addAttribute(ATTR_STOCK, stockDto.getCode());
        document.setRootElement(rootEle);

        for(StockDayDto dayDto : stockDto.getDayList()){
            Element recordEle = factory.createElement(ELE_RECORD);
            recordEle.addAttribute(ATTR_DAY, dayDto.getDay());
            recordEle.addAttribute(ATTR_OPEN, String.valueOf(dayDto.getOpen()));
            recordEle.addAttribute(ATTR_HIGH, String.valueOf(dayDto.getHigh()));
            recordEle.addAttribute(ATTR_LOW, String.valueOf(dayDto.getLow()));
            recordEle.addAttribute(ATTR_CLOSE, String.valueOf(dayDto.getClose()));
            rootEle.add(recordEle);
        }

        FileOutputStream output = null;
        try{
            File xmlFile = new File(configFolder, "stock_" + stockDto.getCode() + ".xml");
            log.info("保存股票数据, file={}", xmlFile.getAbsolutePath());
            output = new FileOutputStream(xmlFile);
            OutputFormat format = new OutputFormat("  ", true, "UTF8");
            XMLWriter writer = new XMLWriter(output, format);
            writer.write(document);
            writer.close();
        }catch(IOException e){
            throw new RuntimeException(e);
        }finally {
            IOUtils.closeQuietly(output);
        }
    }
}
